using System;
using Microsoft.SPOT;
using System.Collections;
using Microsoft.SPOT.Hardware;

public class SafeMessageList
{
    private ArrayList _data = new System.Collections.ArrayList();

    //public object this[object key]
    //{
    //    get
    //    {
    //        try
    //        {
    //            return (_data[key] as DatedObject).Content;
    //        }
    //        catch { }

    //        return null;  
    //    }
    //    set
    //    {
    //        lock (_data.SyncRoot)
    //        {
    //            if (_data.Contains(key))
    //                _data[key] = new DatedObject() { Content = value, CreateTime = PowerState.Uptime };  // update value
    //            else
    //                _data.Add(key, new DatedObject() { Content = value, CreateTime = PowerState.Uptime });  // create new value
    //        }
    //    }
    //}

    public void Add(IMessagePacket item)
    {
        lock (_data.SyncRoot)
        {
            this._data.Add(item);
        }
    }

    public void Remove(IMessagePacket item)
    {
        if (item == null) return;

        lock (_data.SyncRoot)
        {
            try
            {
                if (_data.Contains(item)) _data.Remove(item);
            }
            catch { }
        }
    }

    /// <summary>
    /// Find the oldest item where the opcode is equal to that passed in
    /// </summary>
    /// <param name="opcode"></param>
    /// <returns>The Oldest Message Packet Item</returns>
    public IMessagePacket NextWhere(ushort opcode)
    {
        lock (_data.SyncRoot)
        {
            // Find the Object that was added most recently.  Return the item
            var MinTime = TimeSpan.MaxValue;
            IMessagePacket item = null;

            foreach (IMessagePacket anItem in _data)
            {
                if (anItem.CreateTime < MinTime && opcode == anItem.WaitOpcode)
                {
                    MinTime = anItem.CreateTime;
                    item = anItem;
                }
            }

            return item;
        }
    }

    public bool Any(ushort opcode = 0)
    {
        if (opcode == 0)
        {
            return _data.Count > 0;
        }
        else
        {
            lock (_data.SyncRoot)
            {
                foreach (IMessagePacket anItem in _data)
                {
                    if (anItem.WaitOpcode == opcode) return true;
                }
            }
        }

        return false;
    }

    /// <summary>
    /// Returns the oldest item in the collection
    /// </summary>
    public IMessagePacket Next
    {
        get
        {
            lock (_data.SyncRoot)
            {
                // Find the Object that was added most recently.  Return the key 
                var MinTime = TimeSpan.MaxValue;
                IMessagePacket item = null;

                foreach (IMessagePacket anItem in _data)
                {
                    if (anItem.CreateTime < MinTime)
                    {
                        MinTime = anItem.CreateTime;
                        item = anItem;
                    }
                }

                return item;
            }
        }
    }

    internal void Clear()
    {
        lock (_data.SyncRoot) _data.Clear();
    }

    public int Count 
    {
        get { return _data.Count; } 
    }
}

public interface IMessagePacket
{
    byte[] Content { get; set; }
    ushort WaitOpcode { get; set; }
    TimeSpan CreateTime { get; set; }
}


